package edu.ucdavis.gwt.gis.client.export;

import java.util.LinkedList;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import edu.ucdavis.cstars.client.ESRI;
import edu.ucdavis.cstars.client.Error;
import edu.ucdavis.cstars.client.callback.PrintTaskCallback;
import edu.ucdavis.cstars.client.tasks.PrintParameters;
import edu.ucdavis.cstars.client.tasks.PrintTask;
import edu.ucdavis.cstars.client.tasks.PrintTemplate;
import edu.ucdavis.cstars.client.tasks.PrintTask.PrintResult;
import edu.ucdavis.cstars.client.tasks.PrintTemplate.Format;
import edu.ucdavis.cstars.client.tasks.PrintTemplate.Layout;
import edu.ucdavis.gwt.gis.client.DataManager;
import edu.ucdavis.gwt.gis.client.extras.CloseButton;
import edu.ucdavis.gwt.gis.client.layers.DataLayer;
import edu.ucdavis.gwt.gis.client.layers.DataLayer.DataLayerType;

public class PrintMapPopup extends PopupPanel {

	private static PrintMapPopupUiBinder uiBinder = GWT.create(PrintMapPopupUiBinder.class);
	interface PrintMapPopupUiBinder extends UiBinder<Widget, PrintMapPopup> {}

	private PrintTask printTask = null;

	@UiField HTML printButton;
	@UiField HTML cancelButton;
	@UiField CloseButton close;
	@UiField HTML message;
	@UiField ListBox format;
	@UiField ListBox layout;
	@UiField FlowPanel extraOptions;
	@UiField TextBox title;
	@UiField CheckBox showLegend;
	@UiField ScrollPanel legendSelectSp;
	@UiField VerticalPanel legends;
	@UiField TextBox height;
	@UiField TextBox width;
	@UiField HTML legendMessage;
	
	public PrintMapPopup() {
		setWidget(uiBinder.createAndBindUi(this));
		setStyleName("GwtGisPopup");
		getElement().getStyle().setZIndex(8010);
		setGlassEnabled(true);
		setGlassStyleName("GwtGisPopup-glasspanel");
		
		ESRI.addCorsEnabledServers("utility.arcgisonline.com");
		printTask = PrintTask.create("http://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task");
		//ESRI.addCorsEnabledServers("servicesbeta4.esri.com");
		//printTask = PrintTask.create("http://servicesbeta4.esri.com/arcgis/rest/services/Utilities/ExportWebMap/GPServer/Export%20Web%20Map%20Task");
  	
        close.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				hide();
			}
		});
		cancelButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				hide();
			}
		});
		
		printButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				print();
			}
		});
		
		for( int i = 0; i < Layout.values().length; i++ ) {
			Layout l = Layout.values()[i];
			if( l != Layout.UNKNOWN ) {
				if( l == Layout.MAP_ONLY ) layout.addItem("Just the map", l.getValue());
				else layout.addItem(l.getValue());
			}
			if( l == Layout.A3_LANDSCAPE ) layout.setSelectedIndex(i);
		}
		layout.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				if( getLayout() == Layout.MAP_ONLY ) {
					extraOptions.setVisible(false);
				} else {
					extraOptions.setVisible(true);
				}
			}
		});
		
		for( int i = 0; i < Format.values().length; i++ ) {
			Format f = Format.values()[i];
			if( f != Format.UNKNOWN ) format.addItem(f.getValue());
			if( f == Format.PNG_32 ) format.setSelectedIndex(i);
		}
		
		showLegend.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				updateLegendSelect();
			}
		});
		
		Window.addResizeHandler(new ResizeHandler(){
			@Override
			public void onResize(ResizeEvent event) {
				if( isAttached() ) center();
			}
		});
	}
	
	public void initAndShow() {
		legends.clear();
		message.setHTML("");
		LinkedList<DataLayer> layers = DataManager.INSTANCE.getDataLayers();
		for( DataLayer dl: layers ) {
			if( dl.getType() == DataLayerType.MapServer) {
				CheckBox cb = new CheckBox(dl.getLabel());
				cb.getElement().setAttribute("value", dl.getId());
				legends.add(cb);
			}
		}
		if( legends.getWidgetCount() == 0 ) legends.add(new HTML("No legends to include"));
		
		width.setValue(DataManager.INSTANCE.getMap().getWidth()+"");
		height.setValue(DataManager.INSTANCE.getMap().getHeight()+"");
		
		center();
		
		updateLegendSelect();
	}
	
	public void print() {
		message.setHTML("creating map...");
		PrintParameters params = PrintParameters.create();
		params.setMap(DataManager.INSTANCE.getMap());
		
		PrintTemplate template = PrintTemplate.create();
		template.setFormat(getFormat());
		
		PrintTemplate.LayoutOptions layoutOptions = PrintTemplate.LayoutOptions.create();
		layoutOptions.setTitleText(title.getText());
		layoutOptions.setScalebarUnit("Meters");
		layoutOptions.setLegendLayers(getLegends());
		layoutOptions.setCopyrightText("");
		layoutOptions.setAuthorText("");
		template.setLayoutOptions(layoutOptions);
		
		template.setLayout(getLayout().getValue());
		template.setLabel(title.getText());
		
		template.setExportOptions(PrintTemplate.ExportOptions.create(getInputWidth(), getInputHeight(), 96));
		params.setPrintTemplate(template);
		
		
		printTask.execute(params, 
			new PrintTaskCallback(){
				@Override
				public void onComplete(PrintResult result) {
					Window.open(result.getUrl(), "_blank", "");
					message.setHTML("");
				}
				@Override
				public void onError(Error error) {
					message.setHTML("Error: "+error.getMessage());
				}
		});
	}
	
	private String[] getLegends() {
		LinkedList<String> ids = new LinkedList<String>();
		for( int i = 0; i < legends.getWidgetCount(); i++ ) {
			if( legends.getWidget(i) instanceof CheckBox ) {
				CheckBox cb = (CheckBox) legends.getWidget(i);
				if( cb.getValue() ) {
					ids.add(cb.getElement().getAttribute("value"));
				}
			}
		}
		String[] list = new String[ids.size()];
		for( int i = 0; i < ids.size(); i++ ) {
			list[i] = ids.get(i);
		}
		return list;
	}
	
	private Format getFormat(){
		return Format.get(format.getValue(format.getSelectedIndex()));
	}
	
	private Layout getLayout(){
		return Layout.get(layout.getValue(layout.getSelectedIndex()));
	}
	
	private int getInputWidth() {
		try {
			return Integer.parseInt(width.getText());
		} catch (Exception e) {}
		return 400;
	}
	
	private int getInputHeight() {
		try {
			return Integer.parseInt(height.getText());
		} catch (Exception e) {}
		return 400;
	}

	private void updateLegendSelect() {
		if( showLegend.getValue() ) {
			if( legends.getOffsetHeight() > 100 ) {
				legendSelectSp.setHeight("100px");
			} else {
				legendSelectSp.setHeight(legends.getOffsetHeight()+"px");
			}
			legendMessage.setVisible(true);
			legendSelectSp.getElement().getStyle().setProperty("border", "1px solid #cccccc");
			legendSelectSp.getElement().getStyle().setOpacity(1);
		} else {
			legendSelectSp.getElement().getStyle().setProperty("border", "none");
			legendSelectSp.getElement().getStyle().setOpacity(0);
			legendSelectSp.setHeight("0px");
			legendMessage.setVisible(false);
		}
	}
	
}
